using System.Collections.Generic;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class SmallPetDelayMoveBehavior : SmallPetBaseMoveBehavior
    {
        public float height { get; set; } = 1f;
        public int delayFrame { get; set; }

        private readonly Queue<Vector3> _buffer = new();

        public override void OnUpdate(float dt)
        {
            CheckFarAway();
            if (_buffer.Count <= delayFrame)
            {
                return;
            }

            var targetPos = ProcessPosition(_buffer.Dequeue());
            entity.transform.LookAt(targetPos);
            entity.transform.position = targetPos;
        }

        public override void OnOwnerMove(Vector3 pos, float speedPower)
        {
            _buffer.Enqueue(pos);
        }

        private void CheckFarAway()
        {
            var distance = Vector3.Distance(entity.transform.position, entity.owner.transform.position);
            if (distance < MaxDistance)
            {
                return;
            }

            _buffer.Clear();
            entity.transform.position = entity.owner
                .GetComponent<EntityBindPointComponent>(ETComponentType.EntityBindPoint)
                .GetBindPoint((int)EntityBindPointSmallPetType.Foot).position;
        }

        private Vector3 ProcessPosition(Vector3 pos)
        {
            var offsetXZ = new Vector3(entity.owner.transform.position.x - pos.x, 0,
                entity.owner.transform.position.z - pos.z);
            if (offsetXZ.sqrMagnitude > AvoidRadius * AvoidRadius)
            {
                return new Vector3(pos.x, pos.y - (ViewEntityConst.CharacterHeight - height) * 0.5f, pos.z);
            }

            //与玩家距离太近，调整位置避开
            if (Mathf.Abs(offsetXZ.x) > Mathf.Abs(offsetXZ.z))
            {
                var newOffsetZ = Mathf.Sqrt(AvoidRadius * AvoidRadius - offsetXZ.x * offsetXZ.x);
                return new Vector3(pos.x, pos.y - (ViewEntityConst.CharacterHeight - height) * 0.5f,
                    pos.z - newOffsetZ);
            }

            var newOffsetX = Mathf.Sqrt(AvoidRadius * AvoidRadius - offsetXZ.z * offsetXZ.z);
            return new Vector3(pos.x - newOffsetX, pos.y - (ViewEntityConst.CharacterHeight - height) * 0.5f,
                pos.z);
        }

        private const float MaxDistance = 10f;
        public override uint MaxStore => 4;

        private const float AvoidRadius = 0.5f;

        public override void OnReset()
        {
            base.OnReset();
            _buffer.Clear();
            entity = null;
            delayFrame = 0;
        }
    }
}